/*
	业务总览中的雷达图
*/
define(
	[
		'require',
		'zrender',
		'zrender/tool/util',
		'zrender/tool/color',
		'zrender/Group',
		'zrender/shape/Base',
		'zrender/shape/Image',
		'zrender/shape/Line',
		'zrender/shape/Text',
		'zrender/shape/Rectangle',
		'zrender/shape/Circle',
		'zrender/shape/Sector',
		'zrender/config'
	],
	function (require) {
		"use strict";

		var zrender = require('zrender');
		var BaseShape = require('zrender/shape/Base');
		var ImageShape = require('zrender/shape/Image');
		var LineShape = require('zrender/shape/Line');
		var RectangleShape  = require('zrender/shape/Rectangle');
		var CircleShape = require('zrender/shape/Circle');
		var SectorShape = require('zrender/shape/Sector');
		var TextShape = require('zrender/shape/Text');
		var Group = require('zrender/Group');

		var zrConfig = require('zrender/config');
		var zrUtil = require('zrender/tool/util');
		var zrColor = require('zrender/tool/color');

		var forEach = Ember.EnumerableUtils.forEach,
			map = Ember.EnumerableUtils.map;

		var doublePI = 2*Math.PI
		var BusinessRadar = Ember.Object.extend(Ember.Evented, {
			centerX: 0,

			centerY: 0,

			init: function(){
				if(!this.container){
					return;
				}
				var dom = this.container;

				if(G_vmlCanvasManager && G_vmlCanvasManager.init){
					G_vmlCanvasManager.initElement(dom);
				}

				this._calculateSizeRadius();

				this.zr = zrender.init(dom);

				this.group = new Group();
				this.bgGroup = new Group();
				this.appGroup = new Group();
				this.appShapes = Ember.A();
				this.zr.addGroup(this.group);
				this.group.addChild(this.bgGroup);
				this.group.addChild(this.appGroup);

				this._addEventListner();
			},

			_addEventListner: function(){
				var me = this,
					g = this.appGroup,
					runBind = Ember.run.bind;

				g.bind("mouseover", runBind(this, "_appMouseover"));
				g.bind("mouseout", runBind(this, "_appMouseout"));
				g.bind("click", runBind(this, "_appClick"));
			},

			render: function(){
				var zr = this.zr;

				this.group.position = [this.centerX-this.maxRadius, this.centerY-this.maxRadius];
				// 渲染拓扑图背景
				this._renderBg();

				this._renderScanningLine();
			},

			_renderBg: function(){
				var offset = 20;
				var radius = this.maxRadius - offset;
				var size = Math.max(0, radius*2);
				this.bgShape = new ImageShape({
					hoverable: false,
					position: [offset, offset],
					style: {
						x: 0,
						y: 0,
						width: size,
						height: size,
						image: "resource/img/radar/bg.png"
					}
				});
				this.bgGroup.addChild(this.bgShape);
			},

			_renderScanningLine: function(){
				var me = this,
					zr = this.zr,
					offset = 30,
					radius = this.maxRadius - offset,
					size = Math.max(0, radius);

				//位置坐标和旋转圆点坐标都跟背景图以及扫描图尺寸相关, 如果图片尺寸改变, 需要调整
				this.scanningLine = new ImageShape({
					zlevel: 2,
					hoverable: false,
					position: [offset, offset],
					rotation: [me.slRadian||Math.PI*13/8, radius, radius],
					style: {
						x: 0,
						y: 0,
						width: size,
						height: size,
						image: "resource/img/radar/scanning-clockwise.png"
					}
				});
				this.bgGroup.addChild(this.scanningLine);

				this.startScanAnimate();
			},

			_renderApplications: function(apps){
				var zr = this.zr,
					g = this.appGroup,
					appShapes = this.appShapes,
					maxRadius = this.maxRadius,
					baseRadius = this.maxRadius*244/320;

				var offsetRadian = 0,
					total = apps.length,
					minScale = 0.5,
					maxScale = 1,
					minRespTime = 0,
					maxRespTime = 0,
					minRequest = 0,
					maxRequest = 0;

				// forEach(apps, function(app){
				// 	var pfms = app.performance;
				// 	if(!pfms){
				// 		return;
				// 	}

				// 	var respTime = !pfms.responseTime?0:pfms.responseTime,
				// 		request = !pfms.request?0:pfms.request;

				// 	//minRespTime = Math.min(minRespTime, respTime);
				// 	maxRespTime = Math.max(maxRespTime, respTime);
				// 	//minRequest = Math.min(minRequest, request);
				// 	maxRequest = Math.max(maxRequest, request);
				// });

				forEach(apps, function(app, i){
					var pfms = app.performance,
						appRadian = i*doublePI/total+offsetRadian,
						appRadius = baseRadius,
						appScale = maxScale;

					// if(pfms){
					// 	var respTime = !pfms.responseTime?0:pfms.responseTime,
					// 		request = !pfms.request?0:pfms.request;

					// 	if(maxRespTime > 0){
					// 		appRadius = baseRadius*respTime/maxRespTime;
					// 	}
					// 	if(maxRequest > 0){
					// 		appScale = minScale + (maxScale-minScale)*request/maxRequest;
					// 	}
					// }

					var appShape = new ImageShape({
						clickable: true,
						zlevel: 4,
						position: [
							maxRadius+appRadius*Math.cos(appRadian),
							maxRadius-appRadius*Math.sin(appRadian)
						],
						scale: [appScale, appScale, 0, 0],
						style: {
							x: -32,
							y: -25,
							width: 64,
							height: 51,
							sx: 0,
							sy: 0,
							sWidth: 64,
							sHeight: 50,
							opacity: 1,
							shadowBlur: 3,
							shadowColor: "#000000",
							shadowOffsetX: 2,
							shadowOffsetY: 2,
							image: "resource/img/radar/icon-business.png"
						}
					});
					var appTextShape = new TextShape({
						ignore: true,
						hoverable: false,
						zlevel: 4,
						position: appShape.position,
						scale: appShape.scale,
						style: {
							x: 0,
							y: 45,
							text: app.name,
							textFont: "bold 16px verdana",
							color: 'rgb(200, 200, 200)',
							textAlign: "center",
							shadowBlur: 3,
							shadowColor: "#000000",
							shadowOffsetX: 2,
							shadowOffsetY: 2
						}
					});
					appShape.data = app;
					appShape.radian = appRadian;
					appShape.textShape = appTextShape;
					g.addChild(appShape);
					g.addChild(appTextShape);

					appShapes.push(appShape);
				});
			},

			/**
				调整大小
			*/
			resize: function(){
				var zr = this.zr;
				zr.resize();

				this._calculateSizeRadius();

				this.bgGroup.clearChildren();

				zr.stopAnimation(this.scanningLine);
				this.scanAnimator = null;

				this.render();
				this._appsData&&this.refresh(this._appsData);
			},

			startScanAnimate: function(){
				if(this.scanAnimator){
					return;
				}

				var me = this,
					zr = me.zr,
					offset = 30,
					radius = me.maxRadius - offset,
					scanningLine = me.scanningLine,
					startRadian = scanningLine.rotation[0],
					interval = 15000;

				//如果 开始弧度 不在 doublePI, 则先跑到 弧度0 的位置, 然后开始循环动画, 保证扫描线图形的弧度范围只在0-doublePI之间
				me.scanAnimator = zr.animate(scanningLine, null, startRadian===doublePI)
				.during(function(){
					me._duringScan();
				})
				.when(interval*startRadian/doublePI, {
					rotation: [0, radius, radius]
				})
				.done(function(){
					me.scanAnimator = null;
					if(startRadian!==doublePI){
						zr.modElement(scanningLine.id, {
							rotation: [doublePI, radius, radius]
						});

						me.startScanAnimate();
					}
				})
				.start();
			},

			_duringScan: function(){
				if(this.isMouseEnter){
					return;
				}

				var me = this,
					zr = this.zr,
					scanningLine = me.scanningLine,
					appShapes = me.appShapes,
					slRadian = scanningLine.rotation[0];

				me.slRadian = slRadian;

				//扫描图形的扫描线 弧度0 与 应用图形 弧度0 的最小夹角弧度 为Math.PI/2
				slRadian = slRadian + Math.PI/2;
				if(slRadian < 0){
					//将负数弧度转化为对应的正数弧度
					slRadian = doublePI + slRadian;
				}
				if(slRadian > doublePI){
					slRadian = slRadian - doublePI;
				}

				var isFinished = true;
				appShapes.forEach(function(appShape){
					var apsRadian = appShape.radian;

					//计算扫描线与appShape的最小弧度差 difRadian
					var difRadian = slRadian - apsRadian;
					if(difRadian > Math.PI){
						difRadian = doublePI - difRadian;
					}else if(difRadian < -Math.PI){
						difRadian = doublePI + difRadian;
					}
					difRadian = Math.abs(difRadian);

					if( difRadian < Math.PI/32){
						//如果最小弧度差小于 Math.PI/32, 则已扫描到该app
						if(appShape._isBeingScan == true){
							return;
						}
						appShape._isBeingScan = true;
						appShape._isScanned = true;

						me.autoHoverAppShape = appShape;
						me.hoverAppShape(appShape, true);

						me.activeAppChanged && me.activeAppChanged(appShape.data);
					}else{
						if(appShape._isBeingScan == true){
							appShape._isBeingScan = false;

							me.autoHoverAppShape = null;
							me.autoUnHoverTimer = setTimeout(function(){
								me.unHoverAppShape(appShape);
							}, 1000);
						}
					}

					if( !appShape._isScanned ){
						isFinished = false;
					}
				});

				if(isFinished && appShapes.length > 0){
					if(me._isThisRoundFinished){
						return;
					}
					this.thisRoundFinished && this.thisRoundFinished();
					me._isThisRoundFinished = true;
				}
			},

			hoverAppShape: function(appShape, animate){
				var zr = this.zr,
					performance = appShape.data.performance,
					sy = 0,
					textColor = "";

				if(appShape.hoverAppAnimator){
					return;
				}

				switch(performance.status){
					case 1:
						sy = 102;
						textColor = "rgb(255,205,2)";
						break;
					case 2:
						sy = 153;
						textColor = "rgb(255,0,0)";
						break;
					case 0:
					default:
						sy = 51;
						textColor = "rgb(92,203,57)";
						break;
				}

				zr.modElement(appShape.textShape.id, {
					ignore: false,
					style: {
						color: textColor
					}
				});

				if(!animate){
					zr.modElement(appShape.id, {
						style: {
							opacity: 1,
							sy: sy
						}
					});
					return;
				}

				appShape.hoverAppAnimator = zr.animate(appShape.id, "style", false)
				.when(100, {
					opacity: 0
				})
				.done(function(){
					zr.modElement(appShape.id, {
						style: {
							opacity: 0,
							sy: sy
						}
					});

					zr.animate(appShape, null, false)
					.when(200, {
						scale: [1.1, 1.1, 0, 0]
					})
					.start();

					appShape.hoverAppAnimator = zr.animate(appShape, "style", false)
					.when(200, {
						opacity: 1
					})
					.done(function(){
						appShape.hoverAppAnimator = null;
					})
					.start();
				})
				.start();
			},

			unHoverAppShape: function(appShape){
				var me = this;
				if(!me.zr){
					return;
				}

				if(appShape.hoverAppAnimator){
					appShape.hoverAppAnimator.done(function(){
						me.unHoverAppShape(appShape);
					});
					return;
				}

				me.zr.modElement(appShape.id, {
					scale: [1, 1, 0, 0],
					style: {
						opacity: 1,
						sy: 0
					}
				});
				me.zr.modElement(appShape.textShape.id, {
					ignore: true
				});
			},

			refresh: function(apps){
				clearTimeout(this.autoUnHoverTimer);
				this.appShapes.forEach(function(appShape){
					appShape.hoverAppAnimator&&appShape.hoverAppAnimator.stop();
					appShape.hoverAppAnimator = null;
				});
				this._isThisRoundFinished = false;

				this.autoHoverAppShape = null;
				this._appsData = apps;
				this.appGroup.clearChildren();
				this.appShapes = Ember.A();
				this.zr.painter.clearHover();

				this._renderApplications(apps);
			},

			_appMouseover: function(e){
				if(this.isMouseEnter){
					return;
				}

				this.isMouseEnter = true;
				this.hoverAppShape(e.target);
				clearTimeout(this.autoUnHoverTimer);

				this.activeAppChanged && this.activeAppChanged(e.target.data);

				this.zr.stopAnimation(this.scanningLine);
				this.scanAnimator = null;

				if(this.autoHoverAppShape){
					this.autoHoverAppShape._isBeingScan = false;
				}
			},

			_appMouseout: function(e){
				this.isMouseEnter = false;
				this.unHoverAppShape(e.target);

				this.startScanAnimate();
			},

			_appClick: function(e){
				this.appClicked&&this.appClicked(e.target.data);
			},

			_calculateSizeRadius: function(){
				var dom = this.container;
				this.width = $(dom).width();
				this.height = $(dom).height();
				this.centerX = this.width/2;
				this.centerY = this.height/2;
				this.maxRadius = Math.min(this.width, this.height)/2;
			},

			/**
				销毁拓扑图
			*/
			destroy: function(){
				clearTimeout(this.autoUnHoverTimer);
				this.zr.stopAnimation(this.scanningLine);
				this.scanAnimator = null;
				this.appShapes.forEach(function(appShape){
					appShape.hoverAppAnimator&&appShape.hoverAppAnimator.stop();
					appShape.hoverAppAnimator = null;
				});

				this.autoHoverAppShape = null;
				this.appShapes = null;
				this.scanningLine = null;
				this.container = null;
				this.data = null;
				this.zr.dispose();
				this.zr = null;
			}
		});

		var BusinessRadarView = Ember.Component.extend({
			didInsertElement: function(){
				var view = this;

				var dom = this.$()[0];

				this.chart = BusinessRadar.create({
					container: dom,
					config: this.config,
					activeAppChanged: function(app){
						return view.send("activeAppChanged", app);
					},
					thisRoundFinished: function(){
						return view.send("thisRoundFinished");
					},
					appClicked: function(app){
						return view.send("appClicked", app);
					}
				});
				this.chart.render();

				this.contentChange();

				APM.on("mainContainerResize", this, "_resizeChart");
				APM.on("radarContainerResize", this, "_resizeChart");

				$(document).on("click.hideTopoMenu", function(){
					view.$().find(".btn-group").removeClass("open");
				});
			},

			willDestroyElement: function(){
				APM.off("mainContainerResize");
				APM.off("radarContainerResize");
				$(document).off("click.hideTopoMenu");
				this.chart.destroy();
			},

			contentChange: Ember.observer("content", function(){
				this.chart.refresh( Ember.A(this.get("content")||[]) );
			}),

			_resizeChart: function(){
				this.chart.resize();
			},

			actions: {
				activeAppChanged: Ember.K,
				thisRoundFinished: Ember.K
			}
		});

		return BusinessRadarView;
	}
);
